/**
 * 2024/01/01 - 2024/12/31
 **/
package com.snail.camunda.engin.identity.holder;

import com.snail.camunda.engin.errorcode.CamundaErrorCode;
import com.snail.camunda.engin.identity.dto.GroupInsertDTO;
import com.snail.camunda.engin.identity.dto.GroupModifyDTO;
import com.snail.camunda.engin.identity.dto.GroupQueryDTO;
import com.snail.start.utils.id.ObjectId;
import com.snail.starter.commons.exception.BizException;
import com.snail.starter.commons.page.PageQO;
import com.snail.starter.commons.page.PageVO;
import org.camunda.bpm.engine.IdentityService;
import org.camunda.bpm.engine.identity.Group;
import org.camunda.bpm.engine.identity.GroupQuery;
import org.camunda.bpm.engine.identity.Tenant;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @author: (zg)
 * @Date: 2024/12/16 17:01
 * @Version: 1.0.0
 */
@Component
public class GroupHolder {

    @Resource
    IdentityService identityService;

    public String add(Tenant tenant, GroupInsertDTO dto) {
        Group group = identityService.newGroup(String.valueOf(ObjectId.nextLongId()));
        group.setName(dto.getName());
        group.setType(dto.getType());
        identityService.saveGroup(group);
        if (null != tenant) {
            identityService.createTenantGroupMembership(tenant.getId(), group.getId());
        }
        return group.getId();
    }

    public boolean modify(String id, GroupModifyDTO dto) {
        Group group = queryById(id);
        if (null == group) {
            throw BizException.of(CamundaErrorCode.GROUP_NOT_EXISTS);
        }
        if (null == dto) {
            return true;
        }
        if (null != dto.getName()) {
            group.setName(dto.getName());
        }
        if (null != dto.getType()) {
            group.setType(dto.getType());
        }
        identityService.saveGroup(group);
        return true;
    }

    public Group queryById(String id) {
        GroupQuery groupQuery = createGroupQuery(null);
        groupQuery.groupId(id);
        return groupQuery.singleResult();
    }

    public boolean deleteById(String id) {
        identityService.deleteTenant(id);
        return true;
    }

    public List<Group> list(GroupQueryDTO dto) {
        GroupQuery groupQuery = createGroupQuery(dto);
        return groupQuery.list();
    }


    public PageVO<Group> page(PageQO<GroupQueryDTO> page) {
        GroupQuery groupQuery = createGroupQuery(page.getQuery());
        long count = groupQuery.count();
        if (0 == count) {
            return PageVO.of(page.getPageNum() - 1, page.getPageSize(), 0L, new ArrayList<>());
        }
        return PageVO.of(page.getPageNum(), page.getPageSize(), count, groupQuery.listPage(page.getPageNum(), page.getPageSize()));
    }

    public GroupQuery createGroupQuery(GroupQueryDTO dto) {
        GroupQuery groupQuery = identityService.createGroupQuery();
        if (null == dto) {
            return groupQuery;
        }
        if (null != dto.getName()) {
            groupQuery.groupName("%" + dto.getName() + "%");
        }
        if (null != dto.getType()) {
            groupQuery.groupType(dto.getType());
        }
        return groupQuery;
    }

}